"""
订单管理相关的API
包括订单列表、详情、创建、更新等功能
"""
from flask import request, jsonify, current_app
from flask_jwt_extended import jwt_required, current_user
from sqlalchemy.exc import SQLAlchemyError
from marshmallow import ValidationError
from datetime import datetime

from app.extensions import db
from app.models.order import Order, OrderItem, OrderStatus, PaymentStatus
from app.models.product import Product, ProductVariant
from app.schemas.order import OrderSchema, OrderUpdateSchema, OrderItemSchema
from app.utils.errors import NotFoundError, BadRequestError, ForbiddenError
from app.api.v1 import api_v1

@api_v1.route('/orders', methods=['GET'])
@jwt_required()
def get_orders():
    """获取订单列表"""
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    status = request.args.get('status')
    payment_status = request.args.get('payment_status')
    start_date = request.args.get('start_date')
    end_date = request.args.get('end_date')
    
    # 构建查询
    query = Order.query
    
    # 非管理员只能查看自己的订单
    if not current_user.is_admin:
        query = query.filter_by(user_id=current_user.id)
    
    if status:
        query = query.filter_by(status=status)
    
    if payment_status:
        query = query.filter_by(payment_status=payment_status)
    
    if start_date:
        try:
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
            query = query.filter(Order.created_at >= start_date)
        except ValueError:
            pass
    
    if end_date:
        try:
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
            query = query.filter(Order.created_at <= end_date)
        except ValueError:
            pass
    
    # 分页
    pagination = query.order_by(Order.created_at.desc()).paginate(page=page, per_page=per_page)
    
    return jsonify({
        "total": pagination.total,
        "pages": pagination.pages,
        "page": page,
        "per_page": per_page,
        "orders": [order.to_dict() for order in pagination.items]
    }), 200

@api_v1.route('/orders/<int:order_id>', methods=['GET'])
@jwt_required()
def get_order(order_id):
    """获取订单详情"""
    order = Order.query.get_or_404(order_id)
    
    # 非管理员只能查看自己的订单
    if not current_user.is_admin and order.user_id != current_user.id:
        raise ForbiddenError("权限不足，无法查看其他用户的订单")
    
    return jsonify(order.to_dict(include_items=True)), 200

@api_v1.route('/orders', methods=['POST'])
@jwt_required()
def create_order():
    """创建订单"""
    data = request.get_json()
    
    if not data:
        raise BadRequestError("请求参数为空")
    
    # 验证数据
    schema = OrderSchema()
    try:
        # 使用schema验证数据
        validated_data = schema.load(data)
    except ValidationError as e:
        return jsonify({"msg": "数据验证错误", "errors": e.messages}), 400
    
    # 生成订单编号
    order_number = f"ORD-{datetime.now().strftime('%Y%m%d%H%M%S')}-{current_user.id}"
    
    # 创建订单
    order = Order(
        order_number=order_number,
        user_id=current_user.id,
        status=OrderStatus.PENDING.value,
        total_amount=0,  # 稍后计算
        shipping_address=data['shipping_address'],
        shipping_method=data['shipping_method'],
        payment_method=data['payment_method'],
        payment_status=PaymentStatus.UNPAID.value,
        notes=data.get('notes')
    )
    
    db.session.add(order)
    db.session.flush()  # 获取订单ID
    
    # 添加订单项并计算总金额
    total_amount = 0
    
    for item_data in data['items']:
        product = Product.query.get(item_data['product_id'])
        if not product:
            db.session.rollback()
            return jsonify({"msg": f"商品不存在: {item_data['product_id']}"}), 400
        
        # 确定价格和库存
        if 'variant_id' in item_data and item_data['variant_id']:
            variant = ProductVariant.query.get(item_data['variant_id'])
            if not variant:
                db.session.rollback()
                return jsonify({"msg": f"商品变体不存在: {item_data['variant_id']}"}), 400
            
            price = variant.price
            # 检查库存
            if variant.stock < item_data['quantity']:
                db.session.rollback()
                return jsonify({"msg": f"商品变体库存不足: {variant.sku}"}), 400
            
            # 减少库存
            variant.stock -= item_data['quantity']
        else:
            price = product.price
            # 检查库存
            if product.stock < item_data['quantity']:
                db.session.rollback()
                return jsonify({"msg": f"商品库存不足: {product.sku}"}), 400
            
            # 减少库存
            product.stock -= item_data['quantity']
        
        # 计算小计
        subtotal = price * item_data['quantity']
        total_amount += subtotal
        
        # 创建订单项
        order_item = OrderItem(
            order_id=order.id,
            product_id=item_data['product_id'],
            variant_id=item_data.get('variant_id'),
            quantity=item_data['quantity'],
            price=price,
            subtotal=subtotal
        )
        
        db.session.add(order_item)
    
    # 更新订单总金额
    order.total_amount = total_amount
    
    try:
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        current_app.logger.error(f"创建订单失败: {str(e)}")
        return jsonify({"msg": "创建订单失败", "error": str(e)}), 500
    
    return jsonify({
        "msg": "订单创建成功",
        "order": order.to_dict(include_items=True)
    }), 201

@api_v1.route('/orders/<int:order_id>', methods=['PUT'])
@jwt_required()
def update_order(order_id):
    """更新订单"""
    order = Order.query.get_or_404(order_id)
    
    # 非管理员只能更新自己的订单
    if not current_user.is_admin and order.user_id != current_user.id:
        raise ForbiddenError("权限不足，无法更新其他用户的订单")
    
    data = request.get_json()
    
    if not data:
        raise BadRequestError("请求参数为空")
    
    # 验证数据
    schema = OrderUpdateSchema()
    try:
        # 使用schema验证数据
        validated_data = schema.load(data)
    except ValidationError as e:
        return jsonify({"msg": "数据验证错误", "errors": e.messages}), 400
    
    # 更新字段
    if 'status' in data:
        order.status = data['status']
    if 'payment_status' in data:
        order.payment_status = data['payment_status']
    if 'shipping_address' in data:
        order.shipping_address = data['shipping_address']
    if 'shipping_method' in data:
        order.shipping_method = data['shipping_method']
    if 'payment_method' in data:
        order.payment_method = data['payment_method']
    if 'notes' in data:
        order.notes = data['notes']
    
    try:
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        current_app.logger.error(f"更新订单失败: {str(e)}")
        return jsonify({"msg": "更新订单失败", "error": str(e)}), 500
    
    return jsonify({
        "msg": "订单更新成功",
        "order": order.to_dict()
    }), 200

@api_v1.route('/orders/<int:order_id>', methods=['DELETE'])
@jwt_required()
def delete_order(order_id):
    """删除订单"""
    order = Order.query.get_or_404(order_id)
    
    # 只允许管理员删除订单
    if not current_user.is_admin:
        raise ForbiddenError("权限不足，只有管理员可以删除订单")
    
    try:
        # 删除订单项
        OrderItem.query.filter_by(order_id=order.id).delete()
        
        # 删除订单
        db.session.delete(order)
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        current_app.logger.error(f"删除订单失败: {str(e)}")
        return jsonify({"msg": "删除订单失败", "error": str(e)}), 500
    
    return jsonify({
        "msg": "订单删除成功"
    }), 200

@api_v1.route('/orders/<int:order_id>/cancel', methods=['POST'])
@jwt_required()
def cancel_order(order_id):
    """取消订单"""
    order = Order.query.get_or_404(order_id)
    
    # 非管理员只能取消自己的订单
    if not current_user.is_admin and order.user_id != current_user.id:
        raise ForbiddenError("权限不足，无法取消其他用户的订单")
    
    # 检查订单状态，只有待处理和处理中的订单可以取消
    if order.status not in [OrderStatus.PENDING.value, OrderStatus.PROCESSING.value]:
        return jsonify({"msg": "订单状态不允许取消"}), 400
    
    # 更新订单状态
    order.status = OrderStatus.CANCELLED.value
    
    # 恢复库存
    for item in order.items:
        if item.variant_id:
            variant = ProductVariant.query.get(item.variant_id)
            if variant:
                variant.stock += item.quantity
        else:
            product = Product.query.get(item.product_id)
            if product:
                product.stock += item.quantity
    
    try:
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        current_app.logger.error(f"取消订单失败: {str(e)}")
        return jsonify({"msg": "取消订单失败", "error": str(e)}), 500
    
    return jsonify({
        "msg": "订单取消成功",
        "order": order.to_dict()
    }), 200
